/*
 * Copyright 2010 Michael Nitsche
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

package de.mnit.basis.daten.typ.zeit;

import java.util.Calendar;
import java.util.GregorianCalendar;
import java.util.TimeZone;

import de.mnit.basis.daten.typ.A_Datentyp;
import de.mnit.basis.daten.typ.zeit.format.FORMAT_ZEIT;
import de.mnit.basis.daten.typ.zeit.format.FormatZeit;
import de.mnit.basis.fehler.Fehler;
import de.mnit.basis.fehler.H_Text;
import de.mnit.basis.fehler.system.F_Programm;

/**
 * @author Michael Nitsche
 */
public class Uhrzeit extends A_Datentyp<S_Uhrzeit> implements S_Uhrzeit {

	private final int stunden;
	private final int minuten;
	private final int sekunden;


	public Uhrzeit() {
		GregorianCalendar greg=new GregorianCalendar();
		greg.setTimeZone( TimeZone.getTimeZone("ECT") );
		this.stunden = greg.get(Calendar.HOUR_OF_DAY);
		this.minuten = greg.get(Calendar.MINUTE     );
		this.sekunden= greg.get(Calendar.SECOND     );
	}

	public Uhrzeit(int std, int min, int sek) {
		this.stunden =iPruefe24(std);
		this.minuten =iPruefe60(min);
		this.sekunden=iPruefe60(sek);
	}

	public Uhrzeit(Calendar c) {
		Fehler.objekt.wenn_Null(c);
		this.stunden = c.get(Calendar.HOUR_OF_DAY);
		this.minuten = c.get(Calendar.MINUTE);
		this.sekunden= c.get(Calendar.SECOND);
	}

	public Uhrzeit(long millisek) {
		GregorianCalendar greg=new GregorianCalendar();
		greg.setTimeZone( TimeZone.getTimeZone("ECT") );
		greg.setTimeInMillis(millisek);
		this.stunden = greg.get(Calendar.HOUR_OF_DAY);
		this.minuten = greg.get(Calendar.MINUTE);
		this.sekunden= greg.get(Calendar.SECOND);
	}

	public Uhrzeit(String uhrzeit) {
		Fehler.objekt.wenn_Null(uhrzeit);
		try {
			if(uhrzeit.matches("[0-2][0-9]:[0-5][0-9]:[0-5][0-9]")) {
				this.stunden =iPruefe24(iStringZuZahl(uhrzeit.substring(1-1,2)));
				this.minuten =iPruefe60(iStringZuZahl(uhrzeit.substring(4-1,5)));
				this.sekunden=iPruefe60(iStringZuZahl(uhrzeit.substring(7-1,8)));
			}
			else if(uhrzeit.matches("[0-2][0-9]:[0-5][0-9]")) {
				this.stunden =iPruefe24(iStringZuZahl(uhrzeit.substring(1-1,2)));
				this.minuten =iPruefe60(iStringZuZahl(uhrzeit.substring(4-1,5)));
				this.sekunden=0;
			}
			else throw Fehler.text.da_Ungueltig(uhrzeit);
		}
		catch(F_Programm f)   { throw f; }
		catch(Exception  e)   { throw Fehler.text.da_Ungueltig(uhrzeit); }
	}


	public static Uhrzeit neu(int std, int min, int sek)   { return new Uhrzeit(std,min,sek); }
	public static Uhrzeit neu(String zeit)                 { return new Uhrzeit(zeit); }
	public static Uhrzeit neu(long msek) 	               { return new Uhrzeit(msek); }
	public static Uhrzeit neu()                            { return new Uhrzeit(); }


	// GIB

	public int gStunden() {
		return this.stunden;
	}

	public int gMinuten() {
		return this.minuten;
	}

	public int gSekunden() {
		return this.sekunden;
	}

	public boolean istGroesser(S_Uhrzeit u) {
		long ziel=Zeit.zuMilliSek(u.gStunden(), u.gMinuten(), u.gSekunden(), 0);
		long akt =Zeit.zuMilliSek(gStunden(), gMinuten(), gSekunden(), 0);
		return akt>ziel;
	}

	public boolean istGleich(S_Uhrzeit u) {
		return u.gStunden()==gStunden() && u.gMinuten()==gMinuten() && u.gSekunden()==gSekunden();
	}

	public int diffSek(S_Uhrzeit u) {
		long ziel=Zeit.zuMilliSek(u.gStunden(), u.gMinuten(), u.gSekunden(), 0);
		long akt =Zeit.zuMilliSek(gStunden(), gMinuten(), gSekunden(), 0);
		return (int)(ziel-akt)/1000;
	}

	public String toString() {
		return FormatZeit.zuText(this, FORMAT_ZEIT.GRUPPE_HHMMSS);
	}

	public String zuText(Object... format) {
		return FormatZeit.zuText(this, format);
	}

	public String zuTextEDV() {
		return FormatZeit.zuText(this);
	}

	// INTERN

	private int iPruefe60(int wert) {
		Fehler.zahl.wenn_Ausserhalb(0,59,wert);
		return wert;
	}

	private int iPruefe24(int wert) {
		Fehler.zahl.wenn_Ausserhalb(0,23,wert);
		return wert;
	}

	private int iStringZuZahl(String t) {
		Fehler.text.wenn_Ausserhalb(1,2,t);
//		if(t.charAt(0)==' ' && t.length()==2 && t.charAt(1)>='0' && t.charAt(1)<='9')
//			t=""+t.charAt(1);
		try {
			return Integer.valueOf(t).intValue();
		}
		catch(Exception e) {
			throw H_Text.da_Ungueltig(t);
		}
	}

}
